package dao

import (
	"fmt"
	"time"
	"user_srv/basic/config"
	"user_srv/handler/model"
)

// NotificationService 通知服务
// 负责处理系统通知的发送和管理
// 支持匹配通知、消息通知等多种类型
type NotificationService struct{}

// SendMatchNotification 发送匹配通知
// 功能：在用户匹配成功时，向双方用户发送匹配通知
// 处理流程：
//  1. 获取双方用户的昵称
//  2. 创建通知记录到数据库
//  3. 发送实时推送通知（集成第三方推送服务）
//  4. 通过WebSocket发送匹配成功通知
//
// 参数：
//   - userId1, userId2: 两个匹配成功的用户ID
//   - matchId: 匹配记录ID
func (n *NotificationService) SendMatchNotification(userId1, userId2, matchId int64) error {
	// 1. 获取用户信息（如果获取失败，使用默认昵称）
	user1Nickname := fmt.Sprintf("用户%d", userId1)
	user2Nickname := fmt.Sprintf("用户%d", userId2)

	if user1Profile, err := n.getUserProfile(userId1); err == nil {
		user1Nickname = user1Profile.Nickname
	}

	if user2Profile, err := n.getUserProfile(userId2); err == nil {
		user2Nickname = user2Profile.Nickname
	}

	// 2. 创建通知记录
	notification1 := model.XqNotifications{
		UserId:    userId1,
		Type:      1, // 匹配通知
		Title:     "匹配成功！",
		Content:   fmt.Sprintf("你和 %s 互相喜欢，开始聊天吧！", user2Nickname),
		RelatedId: matchId,
		IsRead:    0,
		CreatedAt: time.Now(),
	}

	notification2 := model.XqNotifications{
		UserId:    userId2,
		Type:      1, // 匹配通知
		Title:     "匹配成功！",
		Content:   fmt.Sprintf("你和 %s 互相喜欢，开始聊天吧！", user1Nickname),
		RelatedId: matchId,
		IsRead:    0,
		CreatedAt: time.Now(),
	}

	// 3. 保存通知到数据库
	if err := notification1.Create(); err != nil {
		return fmt.Errorf("保存用户1通知失败: %v", err)
	}

	if err := notification2.Create(); err != nil {
		return fmt.Errorf("保存用户2通知失败: %v", err)
	}

	// 4. 发送实时推送（这里可以集成第三方推送服务）
	go n.sendRealTimePush(userId1, notification1.Title, notification1.Content)
	go n.sendRealTimePush(userId2, notification2.Title, notification2.Content)

	// 5. 通过WebSocket发送匹配成功通知
	go n.sendMatchWebSocketNotification(userId1, userId2, matchId)
	go n.sendMatchWebSocketNotification(userId2, userId1, matchId)

	return nil
}

// SendMessageNotification 发送消息通知
// 功能：当用户收到新消息时，发送通知给接收者
// 处理流程：
//  1. 获取发送者的昵称
//  2. 创建消息通知记录
//  3. 发送实时推送
//
// 参数：
//   - senderId: 发送者ID
//   - receiverId: 接收者ID
//   - matchId: 匹配关系ID
//   - messageContent: 消息内容
func (n *NotificationService) SendMessageNotification(senderId, receiverId, matchId int64, messageContent string) error {
	// 获取发送者信息（如果获取失败，使用默认昵称）
	senderNickname := fmt.Sprintf("用户%d", senderId)
	if senderProfile, err := n.getUserProfile(senderId); err == nil {
		senderNickname = senderProfile.Nickname
	}

	// 创建消息通知
	notification := model.XqNotifications{
		UserId:    receiverId,
		Type:      2, // 消息通知
		Title:     "新消息",
		Content:   fmt.Sprintf("%s: %s", senderNickname, messageContent),
		RelatedId: matchId,
		IsRead:    0,
		CreatedAt: time.Now(),
	}

	// 保存通知
	if err := notification.Create(); err != nil {
		return fmt.Errorf("保存消息通知失败: %v", err)
	}

	// 发送实时推送
	go n.sendRealTimePush(receiverId, notification.Title, notification.Content)

	return nil
}

// SendCustomNotification 发送自定义类型通知（例如好友动态 Type=3）
func (n *NotificationService) SendCustomNotification(userId int64, typ int8, title, content string, relatedId int64) error {
	notification := model.XqNotifications{
		UserId:    userId,
		Type:      typ,
		Title:     title,
		Content:   content,
		RelatedId: relatedId,
		IsRead:    0,
		CreatedAt: time.Now(),
	}
	return notification.Create()
}

// GetUserNotifications 获取用户通知列表
// 功能：分页获取用户的所有系统通知
// 通知类型：
//   - 匹配通知：新匹配成功
//   - 消息通知：收到新消息
//
// 参数：
//   - userId: 用户ID
//   - page: 页码（从1开始）
//   - pageSize: 每页数量（默认10，最大50）
//
// 返回值：通知列表和总记录数
func (n *NotificationService) GetUserNotifications(userId int64, page, pageSize int32) ([]NotificationInfo, int32, error) {
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 10
	}
	if pageSize > 50 {
		pageSize = 50
	}

	offset := (page - 1) * pageSize

	// 获取通知列表
	var notifications []model.XqNotifications
	err := config.DB.Where("user_id = ?", userId).
		Order("created_at DESC").
		Limit(int(pageSize)).
		Offset(int(offset)).
		Find(&notifications).Error
	if err != nil {
		return nil, 0, err
	}

	// 获取总数
	var total int64
	err = config.DB.Model(&model.XqNotifications{}).Where("user_id = ?", userId).Count(&total).Error
	if err != nil {
		return nil, 0, err
	}

	// 转换为响应格式
	var notificationInfos []NotificationInfo
	for _, notification := range notifications {
		info := NotificationInfo{
			Id:        notification.Id,
			Type:      notification.Type,
			Title:     notification.Title,
			Content:   notification.Content,
			RelatedId: notification.RelatedId,
			IsRead:    notification.IsRead,
			CreatedAt: notification.CreatedAt.Unix(),
		}
		notificationInfos = append(notificationInfos, info)
	}

	return notificationInfos, int32(total), nil
}

// 标记通知为已读
func (n *NotificationService) MarkNotificationAsRead(userId, notificationId int64) error {
	return config.DB.Model(&model.XqNotifications{}).
		Where("id = ? AND user_id = ?", notificationId, userId).
		Update("is_read", 1).Error
}

// 获取未读通知数量
func (n *NotificationService) GetUnreadNotificationCount(userId int64) (int64, error) {
	var notificationModel model.XqNotifications
	return notificationModel.GetUnreadCount(userId)
}

// 批量标记通知为已读
func (n *NotificationService) MarkNotificationsAsRead(userId int64, notificationIds []int64) error {
	if len(notificationIds) == 0 {
		return nil
	}

	return config.DB.Model(&model.XqNotifications{}).
		Where("id IN (?) AND user_id = ?", notificationIds, userId).
		Update("is_read", 1).Error
}

// 删除通知
func (n *NotificationService) DeleteNotification(userId, notificationId int64) error {
	return config.DB.Where("id = ? AND user_id = ?", notificationId, userId).
		Delete(&model.XqNotifications{}).Error
}

// 标记所有通知为已读
func (n *NotificationService) MarkAllNotificationsAsRead(userId int64) error {
	return config.DB.Model(&model.XqNotifications{}).
		Where("user_id = ? AND is_read = 0", userId).
		Update("is_read", 1).Error
}

// 清空用户所有通知
func (n *NotificationService) ClearAllNotifications(userId int64) error {
	return config.DB.Where("user_id = ?", userId).
		Delete(&model.XqNotifications{}).Error
}

// 获取用户资料
func (n *NotificationService) getUserProfile(userId int64) (*model.XqUserProfiles, error) {
	var profile model.XqUserProfiles
	err := config.DB.Where("user_id = ? AND is_active = 1", userId).First(&profile).Error
	return &profile, err
}

// 发送WebSocket匹配通知
func (n *NotificationService) sendMatchWebSocketNotification(userId, matchedUserId, matchId int64) {
	// 获取聊天服务实例
	chatService := GetChatService()

	// 获取匹配用户的信息
	matchedUserNickname := fmt.Sprintf("用户%d", matchedUserId)
	if matchedProfile, err := n.getUserProfile(matchedUserId); err == nil {
		matchedUserNickname = matchedProfile.Nickname
	}

	// 构建WebSocket消息
	wsMessage := map[string]interface{}{
		"type": "match_success",
		"data": map[string]interface{}{
			"match_id":              matchId,
			"matched_user_id":       matchedUserId,
			"matched_user_nickname": matchedUserNickname,
			"message":               fmt.Sprintf("恭喜！你和 %s 互相喜欢，匹配成功！", matchedUserNickname),
			"timestamp":             time.Now().Unix(),
		},
	}

	// 发送WebSocket消息
	if err := chatService.SendWSMessage(userId, wsMessage); err != nil {
		// 如果用户不在线，消息已保存到数据库，用户上线后可以获取
		// log.Printf("发送匹配WebSocket通知失败，用户可能离线: %v", err)
	}
}

// 发送实时推送（模拟实现）
func (n *NotificationService) sendRealTimePush(userId int64, title, content string) {
	// TODO: 这里可以集成第三方推送服务
	// 例如：极光推送、个推、Firebase等
	fmt.Printf("推送通知给用户 %d: %s - %s\n", userId, title, content)
}

// NotificationInfo 通知信息结构体
// 用于返回通知的详细信息
// - Id: 通知ID
// - Type: 通知类型（1=匹配通知，2=消息通知）
// - Title: 通知标题
// - Content: 通知内容
// - RelatedId: 相关记录ID（如匹配ID、消息ID）
// - IsRead: 是否已读（0=未读，1=已读）
// - CreatedAt: 创建时间（Unix时间戳）
type NotificationInfo struct {
	Id        int64  `json:"id"`
	Type      int8   `json:"type"` // 1:匹配通知 2:消息通知
	Title     string `json:"title"`
	Content   string `json:"content"`
	RelatedId int64  `json:"related_id"`
	IsRead    int8   `json:"is_read"`
	CreatedAt int64  `json:"created_at"`
}
